package eip.chapter3.pointtopoint.mule;

import java.io.StringReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.mule.config.i18n.Message;
import org.mule.transformers.AbstractTransformer;
import org.mule.umo.transformer.TransformerException;

import eip.chapter3.pointtopoint.HotelBooking;
import eip.chapter3.pointtopoint.RoomType;

/**
 * We receive a String, and we transform that String to a Hotel booking.
 * 
 * @author Tijs Rademakers
 */
public class XMLToHotelBooking extends AbstractTransformer {
	
	private static final Logger logger = Logger.getLogger(XMLToHotelBooking.class);
	private static final long serialVersionUID = 3688569221501771779L;
	private final SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
	
	/**
	 * Do the transformation 
	 */
	@Override
	protected Object doTransform(Object xmlMessage, String encoding)
			throws TransformerException {
		String bookingString = (String) xmlMessage;		
		try {
			return getHotelBooking(bookingString);
		} catch (DocumentException e) {
			Message msg = Message.createStaticMessage("Error transforming XML to Hotel Booking");
			throw new TransformerException(msg, e);
		}
	}
	
	/**
	 * Transform the regulations from a string to a hotel booking.
	 * 
	 * @param message the xml message to transform
	 * @return the hotel booking
	 * @throws DocumentException if an error occurs.
	 */
	@SuppressWarnings("unchecked")
	private HotelBooking getHotelBooking(String message) throws DocumentException {
		SAXReader reader = new SAXReader();
		Document document = reader.read(new StringReader(message));
		Element bookingElement = document.getRootElement();
		Integer bookingID = Integer.parseInt(bookingElement.attribute(HotelBooking.BOOKING_ID).getText());
		String name = bookingElement.elementText(HotelBooking.NAME);
		String address = bookingElement.elementText(HotelBooking.ADDRESS);
		Date bookingDate = null;
		Date arrivalDate = null;
		Date checkoutDate = null;
		try {
			bookingDate = dateFormat.parse(bookingElement.elementText(HotelBooking.BOOKING_DATE));
		} catch(ParseException p) {
			logger.error("parse exception in booking date " + bookingElement.elementText(
					HotelBooking.BOOKING_DATE), p);
		}
		try {
			arrivalDate = dateFormat.parse(bookingElement.elementText(HotelBooking.ARRIVAL_DATE));
		} catch(ParseException p) {
			logger.error("parse exception in arrival date " + bookingElement.elementText(
					HotelBooking.ARRIVAL_DATE), p);
		}
		try {
			checkoutDate = dateFormat.parse(bookingElement.elementText(HotelBooking.CHECKOUT_DATE));
		} catch(ParseException p) {
			logger.error("parse exception in checkout date " + bookingElement.elementText(
					HotelBooking.CHECKOUT_DATE), p);
		}
		String strRoomType = bookingElement.elementText(HotelBooking.ROOM_TYPE);
		RoomType roomType = null;
		if(RoomType.XML_SINGLE_ROOM.equals(strRoomType)) {
			roomType = RoomType.SINGLE_ROOM;
		} else if(RoomType.XML_DOUBLE_ROOM.equals(strRoomType)) {
			roomType = RoomType.DOUBLE_ROOM;
		} else if(RoomType.XML_SUITE.equals(strRoomType)) {
			roomType = RoomType.SUITE;
		}
		String strSmoking = bookingElement.elementText(HotelBooking.SMOKING);
		Boolean smoking = null;
		if("No".equals(strSmoking)) {
			smoking = Boolean.FALSE;
		} else if("Yes".equals(strSmoking)) {
			smoking = Boolean.TRUE;
		}
		return new HotelBooking(bookingID, name, address, bookingDate, 
				roomType, smoking, arrivalDate, checkoutDate);
	}

}
